#ifndef _DATA_ACCESSOR_H_
#define _DATA_ACCESSOR_H_

#include "collaboration.h"
#include "dbAccessor.h"

/**
* Clase que permite acceder al almacen de metainformacion del sistema.
* Permite abstraer del modelo de almacenamiento de datos usado y acceder
* a este sistema de almacenamiento de forma remota. Implementa el esqueleto
* generado a partir del fichero ICE de definicion de interfaces.
*
* @author Carlos Rodriguez Dominguez
*/
class MIDataAccessor_impl: virtual public Collaboration::MIDataAccessor {
private:
	Collaboration::ListOfApplications m_applications; /**< Conjunto de aplicaciones del sistema */
	DBAccessor m_reader; /**< Lector de datos. En este caso se usa un lector de una BD */
	
	/**
	* Obtiene la posicion en el vector de usuarios de una aplicacion de un
	* usuario concreto
	*
	* @param app Aplicacion
	* @param user Nombre del usuario a buscar
	* @return Posicion del usuario en el vector de usuarios de la aplicacion o -1
	*         si el usuario no existe
	*/
	int getUser(Collaboration::MIApplication& app, const ::std::string& user);
	
	/**
	* Obtiene la posicion en el vector de roles de una aplicacion de un
	* rol concreto
	*
	* @param app Aplicacion
	* @param role Nombre del rol a buscar
	* @return Posicion del rol en el vector de roles de la aplicacion o -1
	*         si el rol no existe
	*/
	int getRole(Collaboration::MIApplication& app, const ::std::string& role);
	
	/**
	* Posicion de una aplicacion en el vector de aplicaciones
	*
	* @param app Nombre de la aplicacion a buscar
	* @return Posicion de la aplicacion en el vector de aplicaciones o -1
	*         si la aplicacion no existe
	*/
	int getApplicationPos(const ::std::string& app);
	
public:
	
	/**
	* Constructor por defecto. Lee los datos del almacen de datos
	*/
	MIDataAccessor_impl();
	
	/**
	* Destructor
	*/
	virtual ~MIDataAccessor_impl();

	/**
	* Obtiene la lista de metainformacion de las aplicaciones
	*
	* @return Lista de metainformacion de las aplicaciones. Si no
	*         hay aplicaciones, devuelve una lista vacia (nunca NULL)
	*/
	virtual ::Collaboration::ListOfApplications getApplications(const Ice::Current& c);
	
	/**
	* Agrega una aplicacion a la lista de aplicaciones del sistema
	*
	* @param app Nombre de la aplicacion a agregar
	* @return True si se pudo agregar la aplicacion. False si ya
	*         existia una aplicacion con igual nombre en el sistema.
	*/
	virtual bool addApplication(const ::std::string& app,
                                const Ice::Current& c);
	
	/**
	* Elimina una aplicacion de la lista de aplicaciones del sistema
	*
	* @param app Nombre de la aplicacion a eliminar
	* @return True si se pudo eliminar la aplicacion. False si no
	*         existia una aplicacion con ese nombre en el sistema.
	*/
	virtual bool removeApplication(const ::std::string& app,
	                                const Ice::Current& c);
	
	/**
	* Loguea a un usuario en el sistema
	*
	* @param app Aplicacion
	* @param user Nombre del usuario a loguear
	* @param pass Password del usuario
	* @return Metainformacion de la conexion realizada. Si hubo algun error,
	*         el campo error_message de la estructura tendra un valor
	*         distinto a la cadena vacia.
	*/
	virtual ::Collaboration::MIConnection login(const ::std::string& app,
                                             const ::std::string& user,
                                             const ::std::string& pass,
                                             const Ice::Current& c);
	
	/**
	* Pone un usuario como conectado. NO se llama automaticamente al llamar
	* al metodo login. Hay que llamarlo explicitamente.
	*
	* @param app Aplicacion del usuario en la que conectarse
	* @param user Usuario a conectar
	* @return Rol que desempeña el usuario o NULL si no pudo conectarse (no existe)
	*/
	virtual ::std::string connectUser(const ::std::string& app,
                                   const ::std::string& user,
                                   const Ice::Current& c);
	
	/**
	* Pone a un usuario como desconectado.
	*
	* @param app Aplicacion del usuario a desconectar
	* @param user Usuario a desconectar
	*/
	virtual void disconnectUser(const ::std::string& app,
                             const ::std::string& user,
                             const Ice::Current& c);
	
	/**
	* Actualiza la marca de tiempo de un usuario. Si esta marca
	* no se actualiza, pasado un cierto tiempo, el usuario debera ser
	* desconectado.
	*
	* @param app Aplicacion del usuario al cual actualizar su marca de tiempo
	* @param user Usuario al cual actualizar su marca de tiempo
	*/
	virtual void updateUserTime(const ::std::string& app,
                             const ::std::string& user,
                             const Ice::Current& c);
	
	/**
	* Cambia el rol de un usuario conectado
	*
	* @param app Aplicacion en la que esta conectado el usuario
	* @param user Usuario al cual cambiar el rol
	* @param role Rol nuevo del usuario
	* @return Nueva metainformacion de la conexion. Si ocurrio algun error,
	*         entonces el campo error_message de la estructura sera distinto
	*         al valor cadena vacia (no NULL).
	*/
	virtual ::Collaboration::MIConnection changeConnectedUserRole(const ::std::string& app,
                                                               const ::std::string& user,
                                                               const ::std::string& role,
                                                               const Ice::Current& c);
	
	/**
	* Obtiene una lista de los usuarios conectados y sus roles actuales correspondientes
	*
	* @param app Aplicacion en la que se encuentran conectados los usuarios
	* @return Matriz con los usuarios y sus roles correspondientes. En la primera
	*         fila de la matriz estan los nombres de los usuarios y en la segunda los
	*         roles de cada uno de ellos. Devuelve NULL si ocurrio algun error.
	*/
	virtual ::Collaboration::ListOfUsersAndRoles connectedUsers(const ::std::string& app,
                                                             const Ice::Current& c);
	
	/**
	* Obtiene una lista con la metainformacion de los usuarios conectados
	*
	* @param app Aplicacion de la que obtener los usuarios conectados
	* @return Lista con la metainformacion de los usuarios conectados o NULL
	*         si ocurre algun error.
	*/
	virtual ::Collaboration::ListOfUsers connectedUsersInfo(const ::std::string& app,
                                                         const Ice::Current& c);
	
	/**
	* Obtiene una lista con la metainformacion de los usuarios de una aplicacion
	*
	* @param app Aplicacion de la cual obtener la metainformacion de los usuarios
	* @return Lista con la metainformacion de los usuarios o NULL si ocurre algun
	*         error.
	*/
	virtual ::Collaboration::ListOfUsers usersInfo(const ::std::string& app,
                                                const Ice::Current& c);
	
	/**
	* Obtiene una lista con la metainformacion de los roles de una aplicacion
	*
	* @param app Aplicacion de la cual obtener la metainformacion de los roles
	* @return Lista con la metainformacion de los roles o NULL si ocurre algun
	*         error.
	*/
	virtual ::Collaboration::ListOfRoles rolesInfo(const ::std::string& app,
                                                const Ice::Current& c);
	
	/**
	* Obtiene la metainformacion de un rol
	*
	* @param app Aplicacion
	* @param role_name Nombre del rol
	* @return Metainformacion del rol o NULL si ocurre algun error
	*/
	virtual ::Collaboration::MIRole roleInfo(const ::std::string& app,
                                          const ::std::string& role_name,
                                          const Ice::Current& c);
	
	/**
	* Obtiene la metainformacion de un usuario
	*
	* @param app Aplicacion
	* @param user_name Nombre del usuario
	* @return Metainformacion del usuario o NULL si ocurre algun error
	*/
	virtual ::Collaboration::MIUser userInfo(const ::std::string& app,
                                          const ::std::string& user_name,
                                          const Ice::Current& c);
	
	
	/**
	* Obtiene una lista con los nombres de los usuarios que pertenecen a un rol
	*
	* @param app Aplicacion a la que pertenecen los usuarios
	* @param role Nombre del rol
	* @return Lista con los nombres de los usuarios que pertenece al rol especificado
	*/
	virtual ::Collaboration::ListOfStrings roleUsers(const ::std::string& app,
                                                  const ::std::string& role,
                                                  const Ice::Current& c);
	
	/**
	* Obtiene una lista con los usuarios conectados cuya marca de tiempo no esta
	* actualizada
	*
	* @param app Aplicacion en la que se encuentran conectados los usuarios
	* @return Lista con los nombres de los usuarios o NULL si ocurrio algun error
	*/
	virtual ::Collaboration::ListOfStrings nonUpdatedUsers(const ::std::string& app,
                                                        const Ice::Current&);
	
	/**
	* Obtiene una lista con los nombres de los roles disponibles para una aplicacion
	*
	* @param app Aplicacion
	* @return Lista con los nombres de los roles disponibles para la aplicacion o NULL
	*        si ocurrio algun error.
	*/
	virtual ::Collaboration::ListOfStrings applicationRoles(const ::std::string& app,
                                                         const Ice::Current& c);
	
	/**
	* Obtiene una lista con los nombres de los usuarios disponibles para una aplicacion
	*
	* @param app Aplicacion
	* @return Lista con los nombres de los usuarios disponibles para la aplicacion o NULL
	*        si ocurrio algun error.
	*/
	virtual ::Collaboration::ListOfStrings applicationUsers(const ::std::string& app,
                                                         const Ice::Current& c);
	
	/**
	* Obtiene una lista con los nombres de los componentes disponibles para una aplicacion
	*
	* @param app Aplicacion
	* @return Lista con los nombres de los componentes disponibles para la aplicacion o NULL
	*        si ocurrio algun error.
	*/
	virtual ::Collaboration::ListOfStrings applicationComponents(const ::std::string& app,
                                                              const Ice::Current& c);
	
	/**
	* Obtiene una lista con la metainformacion de los roles disponibles para un usuario
	*
	* @param app Aplicacion a la que pertenece el usuario
	* @param user Nombre del usuario
	* @return Lista con la metainformacion de los roles disponibles para un usuario o
	*         NULL si ocurrio algun error.
	*/
	virtual ::Collaboration::ListOfRoles allowedRoles(const ::std::string& app,
                                                   const ::std::string& user,
                                                   const Ice::Current& c);
	
	/**
	* Obtiene una lista con los nombres de los roles disponibles para un usuario
	*
	* @param app Aplicacion a la que pertenece el usuario
	* @param user Nombre del usuario
	* @return Lista con los nombres de los roles disponibles para un usuario o
	*         NULL si ocurrio algun error.
	*/
	virtual ::Collaboration::ListOfStrings allowedRoleNames(const ::std::string& app,
                                                         const ::std::string& user,
                                                         const Ice::Current& c);
	
	/**
	* Obtiene el nivel de permisos de un componente para un usuario
	*
	* @param app Aplicacion
	* @param user Usuario
	* @param comp Componente
	* @return Nivel de permisos del componente o -1 si ocurrio algun error
	*/
	virtual ::Ice::Int getUserComponentPermissions(const ::std::string& app,
                                                const ::std::string& user,
                                                const ::std::string& comp,
                                                const Ice::Current& c);
	
	/**
	* Asigna un nivel de permisos para un componente y un usuario concreto
	*
	* @param app Aplicacion
	* @param user Usuario
	* @param comp Componente
	* @param level Nivel de permisos nuevo para el componente y el usuario
	* @return True si se pudo asignar el nivel de permisos. False en caso contrario
	*/
	virtual bool setUserComponentPermissions(const ::std::string& app,
                                          const ::std::string& user,
                                          const ::std::string& comp,
                                          ::Ice::Int level,
                                          const Ice::Current& c);
	
	/**
	* Obtiene el nivel de permisos de un componente para un rol
	*
	* @param app Aplicacion
	* @param role Rol
	* @param comp Componente
	* @return Nivel de permisos del componente o -1 si ocurrio algun error
	*/
	virtual ::Ice::Int getRoleComponentPermissions(const ::std::string& app,
                                                const ::std::string& role,
                                                const ::std::string& comp,
                                                const Ice::Current& c);
	
	/**
	* Asigna un nivel de permisos para un componente y un rol concreto
	*
	* @param app Aplicacion
	* @param role Rol
	* @param comp Componente
	* @param level Nivel de permisos nuevo para el componente y el rol
	* @return True si se pudo asignar el nivel de permisos. False en caso contrario
	*/	
	virtual bool setRoleComponentPermissions(const ::std::string& app,
                                          const ::std::string& role,
                                          const ::std::string& comp,
                                          ::Ice::Int level,
                                          const Ice::Current& c);
	
	/**
	* Obtiene el rol actual de un usuario
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return Nombre del rol actual de un usuario o NULL si ocurrio algun error
	*/
	virtual ::std::string userActualRole(const ::std::string& app,
	                                      const ::std::string& user,
	                                      const Ice::Current& c);
	
	/**
	* Crea un nuevo rol permitido para un usuario
	*
	* @param app Aplicacion
	* @param user Usuario
	* @param role Rol
	* @return True si se pudo crear el rol permitido o False en caso contrario.
	*/
	virtual bool newUserAllowedRole(const ::std::string& app,
                                 const ::std::string& user,
                                 const ::std::string& role,
                                 const Ice::Current& c);
	
	/**
	* Crea un nuevo usuario para una aplicacion
	*
	* @param app Aplicacion
	* @param user Usuario
	* @param password Clave
	* @param default_role Rol por defecto del usuario
	* @param is_admin Indica si es un usuario administrador o no
	* @return True si se pudo crear el usuario o False en caso contrario
	*/
 	virtual bool newUser(const ::std::string& app,
                      	const ::std::string& user,
                      	const ::std::string& password,
                      	const ::std::string& default_role,
                      	bool is_admin,
                      	const Ice::Current& c);
							
	/**
	* Crea un nuevo rol para una aplicacion
	*
	* @param app Aplicacion
	* @param role Rol
	* @return True si se pudo crear el rol o False en caso contrario
	*/
	virtual bool newRole(const ::std::string& app,
                      const ::std::string& role,
                      const Ice::Current& c);
	
	/**
	* Elimina un rol permitido para un usuario
	*
	* @param app Aplicacion
	* @param user Usuario al que eliminar el rol permitido
	* @param role Rol a eliminar
	* @return True si todo fue correcto o False en caso contrario.
	*/
	virtual bool removeAllowedUserRole(const ::std::string& app,
                                    const ::std::string& user,
                                    const ::std::string& role,
                                    const Ice::Current& c);
	
	/**
	* Elimina un usuario de una aplicacion
	*
	* @param app Aplicacion
	* @param user Usuario
	* @return True si se pudo eliminar el usuario o False en caso contrario
	*/
	virtual bool removeUser(const ::std::string& app,
                         const ::std::string& user,
                         const Ice::Current& c);
	
	/**
	* Elimina un rol de una aplicacion
	*
	* @param app Aplicacion
	* @param role Rol
	* @return True si se pudo eliminar el rol o False en caso contrario
	*/
	virtual bool removeRole(const ::std::string& app,
                         const ::std::string& role,
                         const Ice::Current& c);
	
	/**
	* Obtiene una lista con los nombres de las aplicaciones del sistema
	*
	* @return Lista con los nombres de las aplicaciones del sistema
	*/
	virtual ::Collaboration::ListOfStrings getApplicationsNames(const Ice::Current& c);
	
	/**
	* Obtiene la metainformacion de una aplicacion
	*
	* @param name Nombre de la aplicacion
	* @return Metainformacion de la aplicacion o NULL si ocurrio algun error
	*/
	virtual ::Collaboration::MIApplication getApplication(const ::std::string& name,
                                                       const Ice::Current& c);
	
	/**
	* Guarda la metainformacion del sistema de manera persistente
	*/
	virtual void commit(const Ice::Current& c);
};

#endif
